from django.shortcuts import render
from rest_framework.generics import CreateAPIView
from rest_framework.views import APIView
from rest_framework.response import Response
from django_redis import get_redis_connection
import pickle, base64

# Create your views here.
from carts.serializers import CartSerialziers, SKUSerialziers
from goods.models import SKU


class CartsView(APIView):
    def perform_authentication(self, request):
        # 在调用方法之前先不进行用户验证
        pass

    def post(self, request):
        """
            保存购物车
        :param request:
        :return:
        """
        # 1、获取前端数据
        data = request.data
        # 2、验证数据
        ser = CartSerialziers(data=data)
        # ser.is_valid(raise_exception=True)
        ser.is_valid()
        print(ser.errors)

        sku_id = ser.validated_data['sku_id']
        count = ser.validated_data['count']
        selected = ser.validated_data['selected']

        # 判断用户是否登录
        try:
            user = request.user
        except:
            user = None

        if user is not None:
            # 用户已登录
            # 1、建立缓存连接
            conn = get_redis_connection('cart')
            # 2、保存hash类型和集合类型
            conn.hincrby('cart_%s' % user.id, sku_id, count)
            if selected:
                conn.sadd('cart_selected_%s' % user.id, sku_id)
            # 3、返回结果
            return Response('ok')

        else:
            # 1、先判断是否有cookie存在
            cart_cookie = request.COOKIES.get('cart_cookie')
            if cart_cookie:
                cart = pickle.loads(base64.b64decode(cart_cookie))
            else:
                # 2、没有cookie定义一个空字典
                cart = {}

            """
            {
                sku_id:{
                    'count':2,
                    'selected':True
                },
                 sku_id2:{
                    'count':3,
                    'selected':False
                }
            }
            """
            # 3、有cookie获取cookie值累加
            sku_dict = cart.get(sku_id)
            if sku_dict:
                count += int(sku_dict['count'])

            cart[sku_id] = {
                'count': count,
                'selected': selected
            }
            # 4、将新的字典数据写入cookie
            response = Response('ok')
            # 加密写入后的字典数据
            cart_cookie = base64.b64encode(pickle.dumps(cart)).decode()
            response.set_cookie('cart_cookie', cart_cookie, max_age=60 * 60 * 24 * 7)
            # 5、返回结果
            return response

    def get(self, request):
        """
            获取购物车
        :param request:
        :return:
        """
        # 判断用户是否登录
        try:
            user = request.user
        except:
            user = None

        if user is not None:
            # 用户已登录
            # 1、建立缓存连接
            conn = get_redis_connection('cart')
            # 2、获取hash类型和集合类型
            sku_id_count = conn.hgetall('cart_%s' % user.id)  # {16:1}
            sku_selected = conn.smembers('cart_selected_%s' % user.id)  # {16}
            # 转化为完整的购物车数据
            cart = {}
            for sku_id, count in sku_id_count.items():
                cart[int(sku_id)] = {
                    'count': int(count),
                    'selected': sku_id in sku_selected
                }

        else:
            # 1、先判断是否有cookie存在
            cart_cookie = request.COOKIES.get('cart_cookie')
            if cart_cookie:
                cart = pickle.loads(base64.b64decode(cart_cookie))
            else:
                # 2、没有cookie定义一个空字典
                cart = {}

        # 查询商品对象
        skus = SKU.objects.filter(id__in=cart.keys())

        for sku in skus:
            sku.count = cart[sku.id]['count']
            sku.selected = cart[sku.id]['selected']

        ser = SKUSerialziers(skus, many=True)
        return Response(ser.data)
